import { instantiate } from "../../public/core"; // generated file, see asconfig.json

const __moduleInfo = {
  inited: false,
  loading: false,
  wasm: undefined,
};

const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));

async function loadModule(){
  while (__moduleInfo.loading){
    await sleep(50);
  }
  if (__moduleInfo.inited){
    return __moduleInfo.wasm;
  }
  __moduleInfo.loading = true;
  const module = await WebAssembly.compileStreaming(fetch("core.wasm"));
  const wasm = await instantiate(module);
  __moduleInfo.wasm = wasm;
  __moduleInfo.inited = true;
  __moduleInfo.loading = false;
  return wasm;
}

/**
 * micropython MONO_HLSB to ImageDataArray, using WASM
 * @param {Uint8Array} data 
 * @param {number} imgWidth 
 * @param {number} imgHeight 
 * @param {number} [scale=1]
 * @param {[number,number,number]} [color=[0,0,0]]
 * @param {[number,number,number]} [backgroundColor=[-1,-1,-1]]
 * @returns {Promise<Uint8Array>}
 */
export async function drawCanvasData(data, imgWidth, imgHeight, scale=1, color=[0x00,0x00,0x00], backgroundColor=[-1,-1,-1]){
  const module = await loadModule();
  return module.drawCanvasData(data, imgWidth, imgHeight, scale, color, backgroundColor);
}

/**
 * parse MONO_HLSB data from canvas image data
 * @param {Uint8Array} data 
 * @param {number} imgWidth 
 * @param {number} imgHeight 
 * @param {number} scale scale
 * @param {[number,number,number]} color color which is 1
 * @returns {Promise<Uint8Array>}
 */
export async function parseDataFromCanvas(data, imgWidth, imgHeight, scale=1, color=[0x00,0x00,0x00]){
  const module = await loadModule();
  return module.parseDataFromCanvas(data, imgWidth, imgHeight, scale, color);
}

/**
 * convert canvas image data to gray scale image
 * @param {Uint8Array} data 
 * @returns {Promise<Uint8Array>}
 */
export async function convertToGrayScale(data){
  const module = await loadModule();
  return module.convertToGrayScale(data);
}

/**
 * convert canvas image data to black and white image
 * @param {Uint8Array} data 
 * @param {number} grayThreshold should be in [0,255]
 * @returns {Promise<Uint8Array>}
 */
export async function convertToBlackWhite(data, grayThreshold=127){
  const module = await loadModule();
  return module.convertToBlackWhite(data, grayThreshold);
}

/**
 * convert canvas image data to black and white image
 * @param {Uint8Array} data 
 * @param {number} imgWidth 
 * @returns {Promise<Uint8Array>}
 */
export async function convertToBlackWhiteDither(data, imgWidth){
  const module = await loadModule();
  return module.convertToBlackWhiteDither(data, imgWidth);
}

/**
 * convert canvas image data to black and white image
 * @param {Uint8Array} data 
 * @param {number} imgWidth 
 * @returns {Promise<Uint8Array>}
 */
export async function convertToBlackWhiteFloydSteinberg(data, imgWidth){
  const module = await loadModule();
  return module.convertToBlackWhiteFloydSteinberg(data, imgWidth);
}

export default {
  drawCanvasData,
  parseDataFromCanvas,
  convertToGrayScale,
  convertToBlackWhite,
  convertToBlackWhiteDither,
  convertToBlackWhiteFloydSteinberg,
}